package br.edu.ufcg.splab.simulator;

import java.util.ArrayList;
import java.util.List;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;

import br.edu.ufcg.splab.core.InterfaceEdge;
import br.edu.ufcg.splab.core.InterfaceGraph;

public class TestSimulator {

	List<InterfaceGraph> lista;
	
	int depth = 50;
	int quantity = 1; 
	int nLoops = 15;
	int nJoins = 23;
	int nForks = 20;
	int countJoin = 0;
	int countLoop = 0;
	int countFork = 0;
	
	ArrayList<InterfaceEdge> visited  = new ArrayList<InterfaceEdge>();

	LTSSimulator simulator = new LTSSimulator();



	@Before
	public void creat(){
		try {
			lista  =  simulator.getSimulatedLTS(depth,quantity,nLoops,nJoins,nForks);
		} catch (Exception e) {
			e.getMessage();
		}	
	}

	@Test
	public void testSuiteOfGraphs(){
		//checa a quantidade grafos gerados
		Assert.assertEquals(lista.size(),quantity);

		for (int i = 0; i < quantity ; i++) {

			//checa numero de arestas	
			Assert.assertEquals(nLoops + depth + nJoins*2 + nForks*2, lista.get(i).getEdges().size());
			// assim eh o de Francisco nLoops + depth*2 + nJoins*3 + nForks*4

			//checa numero de nos
			Assert.assertEquals(depth + 1 + nJoins + nForks*2, lista.get(i).getStates().size());

			//raiz nao tem loop
			Assert.assertEquals(0,lista.get(i).getRoot().getInTransitions().size());

		}
		
		//checa numero de loops,joins e forks
		
		contaloops(lista.get(0));
		Assert.assertEquals(countLoop,nLoops);
		Assert.assertEquals(countJoin/2, nJoins);
		Assert.assertEquals(countFork/2, nForks);
		
	}
	
	
	
	
	
	//uma edge eh loop se o level vertice inicial eh maior que o vertice de destino.
			private boolean isLoop(InterfaceEdge edge){
				
				if((simulator.getLevels().get(edge.getFrom())) > (simulator.getLevels().get(edge.getTo()))){
					return true;
				}
				return false;
			}

			private void contaloops(InterfaceGraph graph){
				for(int i = 0;i < depth; i++){
					visited.add(graph.getEdges().get(i));
				}
				
				for(InterfaceEdge edge : graph.getEdges()){
					if(isLoop(edge) && !visited.contains(edge)){
						visited.add(edge);
						countLoop++;
					}
					else if(isJoin(edge) && !visited.contains(edge)){
						visited.add(edge);
						countJoin++;
					}
					else if(!visited.contains(edge)){
						countFork++;
					}
				}
				
			}
			
			private boolean isJoin(InterfaceEdge edge) {
				if(edge.getTo().getInTransitions().size() > 1){	
					return true;
				}
				return false;
			}
			
	/**@Test
	public void testGraph(){
		TestSuite suite = new TestSuite();
		TestCaseGenerator testCase = new TestCaseGenerator();

		for (int i = 0; i < quantity ; i++) {
			suite = (testCase.generate(lista.get(i)));
			//percorre conjunto de paths em um grafo
			for(TestCase path : suite){
				//percorre edges de um path,-1 para nao chegar nas folhas
				for(int j = 0; j < path.toArray().size()-1 ; j++ ){

					if(path.toArray().get(j).getType().equals("CONDITIONS")){
						Assert.assertTrue(path.toArray().get(j+1).getType().equals("EXPECTED_RESULTS"));
					}
					else if(path.toArray().get(j).getType().equals("EXPECTED_RESULTS")){
						Assert.assertTrue(path.toArray().get(j+1).getType().equals("CONDITIONS"));
					}
				}	
			}
		}	 **/
//	}





}

